/*
    D2D is an extremely small and fast windows-2d-game-engine.

    features:

        support bmp, jpg, gif picture format.
        utf-8 string.
        support wav and midi sound format.
        usually, game of cpu utilization rate is 0%!
        the smallest compiled-exe is only 21kb!

    :(
        run only in windows.
        no sprites, no particles, no editor, no alpha-blending, no png, no rotation.

    license:
        freely. you can deal it in any way.

    gamcat@gmail.com
*/

#ifndef D2D_H
#define D2D_H

#include <stdio.h>
#include <windows.h>

#define main() WINAPI WinMain (HINSTANCE a, HINSTANCE b, LPSTR c, int d)

/* keyboard and mouse button id */
#define K_LBUTTON	0x01
#define K_RBUTTON	0x02
#define K_MBUTTON	0x04

#define K_ESCAPE	0x1B
#define K_BACKSPACE	0x08
#define K_TAB		0x09
#define K_ENTER		0x0D
#define K_SPACE		0x20

#define K_SHIFT		0x10
#define K_CTRL		0x11
#define K_ALT		0x12

#define K_LWIN		0x5B
#define K_RWIN		0x5C
#define K_APPS		0x5D

#define K_PAUSE		0x13
#define K_CAPSLOCK	0x14
#define K_NUMLOCK	0x90
#define K_SCROLLLOCK 0x91

#define K_PGUP		0x21
#define K_PGDN		0x22
#define K_HOME		0x24
#define K_END		0x23
#define K_INSERT	0x2D
#define K_DELETE	0x2E

#define K_LEFT		0x25
#define K_UP		0x26
#define K_RIGHT		0x27
#define K_DOWN		0x28

#define K_0			0x30
#define K_1			0x31
#define K_2			0x32
#define K_3			0x33
#define K_4			0x34
#define K_5			0x35
#define K_6			0x36
#define K_7			0x37
#define K_8			0x38
#define K_9			0x39

#define K_A			0x41
#define K_B			0x42
#define K_C			0x43
#define K_D			0x44
#define K_E			0x45
#define K_F			0x46
#define K_G			0x47
#define K_H			0x48
#define K_I			0x49
#define K_J			0x4A
#define K_K			0x4B
#define K_L			0x4C
#define K_M			0x4D
#define K_N			0x4E
#define K_O			0x4F
#define K_P			0x50
#define K_Q			0x51
#define K_R			0x52
#define K_S			0x53
#define K_T			0x54
#define K_U			0x55
#define K_V			0x56
#define K_W			0x57
#define K_X			0x58
#define K_Y			0x59
#define K_Z			0x5A

#define K_GRAVE		0xC0
#define K_MINUS		0xBD
#define K_EQUALS	0xBB
#define K_BACKSLASH	0xDC
#define K_LBRACKET	0xDB
#define K_RBRACKET	0xDD
#define K_SEMICOLON	0xBA
#define K_APOSTROPHE 0xDE
#define K_COMMA		0xBC
#define K_PERIOD	0xBE
#define K_SLASH		0xBF

#define K_NUMPAD0	0x60
#define K_NUMPAD1	0x61
#define K_NUMPAD2	0x62
#define K_NUMPAD3	0x63
#define K_NUMPAD4	0x64
#define K_NUMPAD5	0x65
#define K_NUMPAD6	0x66
#define K_NUMPAD7	0x67
#define K_NUMPAD8	0x68
#define K_NUMPAD9	0x69

#define K_MULTIPLY	0x6A
#define K_DIVIDE	0x6F
#define K_ADD		0x6B
#define K_SUBTRACT	0x6D
#define K_DECIMAL	0x6E

#define K_F1		0x70
#define K_F2		0x71
#define K_F3		0x72
#define K_F4		0x73
#define K_F5		0x74
#define K_F6		0x75
#define K_F7		0x76
#define K_F8		0x77
#define K_F9		0x78
#define K_F10		0x79
#define K_F11		0x7A
#define K_F12		0x7B


/* picture datastruct */
typedef struct {
    int w;
    int h;
    DWORD colorkey;
    void *surface; /* ddraw LPDIRECTDRAWSURFACE */
} D2DImage;

/*
 * function type for game loop.
 * param is the during-seconds between two frames.
 * return FALSE to quit loop. eg.
 *
   BOOL loopf (double dt)
   {
     if (d2d_iskeydown(K_ESCAPE))
       return FALSE;

     cat.x += SPEEDX * dt;

     return TRUE;
   }
 */
typedef BOOL (*D2D_LOOPFUNC) (double);


/* shoud call it first, to create main window and init DirectDraw.
 * return window handle.
 */
HWND d2d_open(int w, int h);

/*
 * global setting
 *
 * eg.
 * d2d_set("title", "mario"); //set window title
 * d2d_set("icon", "logo.ico"); // set window small icon
 * d2d_set("fps", 30);
 */
void d2d_set(const char* p, ...);

void d2d_msgbox (const char *info);

void* d2d_loadrc(const char *rctype, const char* rcname, int *rclen);

BOOL d2d_iskeydown (int kid);
BOOL d2d_iskeyup (int kid);

/* return if mouse in window client */
BOOL d2d_mousein();

/* get mouse position */
void d2d_getmousexy (int *x, int *y);

/* show/hide mouse */
void d2d_showmouse (BOOL yes);

/* this call a winapi: QueryPerformanceCounter,
 * return the cpu clock by second.
 */
double d2d_clock ();

/* set and run game loop */
void d2d_run (D2D_LOOPFUNC func);

/* get fps */
double d2d_fps ();

/* fill screen with a RGB color */
void d2d_clrscr (DWORD color);

/* call it at the end of game loop */
void d2d_flip ();

/* eg.
 * d2d_newimage("GIF:cat.gif", 0); //load from rc.
 * d2d_newimage("f:/p/cat.gif", 0); //load from file.
 */
D2DImage*
d2d_newimage(char *path, DWORD colorkey);

void d2d_freeimage (D2DImage *img);

/* blit image to (x,y) */
void d2d_blt (D2DImage *img, float x, float y);
/* blit part of the image to (x,y) */
void d2d_bltp (D2DImage *img, float x, float y, RECT *src);
/* blit part of the image to (x,y) and zoom */
void d2d_bltz (D2DImage *img, float x, float y, RECT *src, float zoom);


/* font */
/*
color format is RGB
weight type: thin, normal, bold, bolder
facename: like verdana, courier, Arial, ...
*/
HFONT d2d_newfont (int size, const char* weight, const char *facename);
void d2d_freefont (HFONT font);
void d2d_gotoxy(int x, int y);
void d2d_setfontcolor(DWORD color);
int d2d_print (HFONT font, const char *format, ...);


/* play WAVE sound
    d2d_playsound("beep.wav"); // play beep.wav file
    d2d_playsound(":beep"); // play a WAVE type resource named beep
*/
void d2d_playsound (const char* filename);
void d2d_stopsound();


/* param format:
 * "MIDI:xx" (from rc)
 * "xx.mid" (from file)
 */
HANDLE d2d_midi_loadsong(const char *filename);
void d2d_midi_freesong(HANDLE song);
void d2d_midi_playsong(HANDLE song);
void d2d_midi_stop();
BOOL d2d_midi_playing();
void d2d_midi_setvolume(int volume);


/* you can bind variable to a string name,
 * and get it anytime and anywhere.
 */
void d2d_setvar(const char* name, void* var);
void* d2d_getvar(const char* name);

#endif
